#pragma once

#include "wfx.h"
#include "TokenBasic.h"
#include <string>
#include <hash_map>

MAKE_PTR(CTokenManager);
MAKE_PTR(CScannerRule);

#ifndef TOKEN_DEBUG_STRING
#define TOKEN_DEBUG_STRING(nTokenType)\
    (CTokenManager::Instance()->GetTokenDebugString(nTokenType))
#endif

class CTokenManager
{
public:

    static CTokenManagerPtr Instance()
    {
        static CTokenManagerPtr pInstance(new CTokenManager());
        return pInstance;
    }

    ~CTokenManager();

private:
    CTokenManager();

    CTokenManager(const CTokenManager&);

    CTokenManager& operator = (const CTokenManager&);

public:

    void SetScannerRule(CScannerRulePtr pScannerRule);

    int AddTokenDebugString(Token_Type Token, std::string strDebugString);

    const std::string& GetTokenDebugString(Token_Type Token);

    Token_Type NonterminateToken(std::string str, Token_Type type = 0);

    Token_Type Keyword(std::string str, Token_Type type = 0);

    Token_Type SpecialToken(std::string str, Token_Type type = 0);

private:

    CScannerRulePtr m_pScannerRule;

    std::string m_strNoDebugString;

    stdext::hash_map<Token_Type,std::string> m_TokenDebugStringMap;

    stdext::hash_map<std::string, Token_Type> m_Keyword;

    stdext::hash_map<std::string, Token_Type> m_NonterminateToken;

    stdext::hash_map<std::string, Token_Type> m_SpectialToken;

    int m_nonterminateID;

    int m_terminateID;

private:

    int GenerateTerminateID();
    int GenerateNonTerminateID();
};